<?php
/**
 * Created by PhpStorm.
 * User: SongKejing
 * QQ: 597481334
 * Date: 2017/11/30
 * Time: 9:35
 */

namespace ClassLibrary;

use app\index\model\BaseModel;

/**
 * 字段校验
 * Class ClFieldVerify
 * @package ClassLibrary
 */
class ClFieldVerify extends ClFieldBase {

    /**
     * 消息
     * @var string
     */
    private static $msg = '';

    /**
     * 获取描述名称
     * @param $filters
     * @return string
     */
    public function getNamesStringByVerifies($filters) {
        $filters_desc = [];
        foreach ($filters as $v_verify) {
            $message = '';
            if (is_array($v_verify)) {
                if (strpos($v_verify[0], ':') !== false) {
                    list($v_verify[0], $message) = explode(':', $v_verify[0]);
                    $message = ':' . $message;
                }
                switch ($v_verify[0]) {
                    case 'password':
                        $filters_desc[] = sprintf('密码长度%s~%s', $v_verify[1], $v_verify[2]) . $message;
                        break;
                    case 'in_array':
                        $filters_desc[] = sprintf('在%s数组内', json_encode($v_verify[1], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)) . $message;
                        break;
                    case 'in_scope':
                        $filters_desc[] = sprintf('在[%s, %s]区间内', $v_verify[1], $v_verify[2]) . $message;
                        break;
                    case 'max':
                        $filters_desc[] = sprintf('最大值%s', $v_verify[1]) . $message;
                        break;
                    case 'min':
                        $filters_desc[] = sprintf('最小值%s', $v_verify[1]) . $message;
                        break;
                    case 'length':
                        $filters_desc[] = sprintf('长度为%s', $v_verify[1]) . $message;
                        break;
                    case 'length_max':
                        $filters_desc[] = sprintf('最大长度%s', $v_verify[1]) . $message;
                        break;
                    case 'length_min':
                        $filters_desc[] = sprintf('最小长度%s', $v_verify[1]) . $message;
                        break;
                }
            } else {
                if (strpos($v_verify, ':') !== false) {
                    list($v_verify, $message) = explode(':', $v_verify);
                    $message = ':' . $message;
                }
                switch ($v_verify) {
                    case 'is_required':
                        $filters_desc[] = '必填' . $message;
                        break;
                    case 'email':
                        $filters_desc[] = '邮箱格式' . $message;
                        break;
                    case 'mobile':
                        $filters_desc[] = '手机号' . $message;
                        break;
                    case 'ip':
                        $filters_desc[] = 'ip地址' . $message;
                        break;
                    case 'postcode':
                        $filters_desc[] = '邮编' . $message;
                        break;
                    case 'id_card':
                        $filters_desc[] = '身份证' . $message;
                        break;
                    case 'chinese':
                        $filters_desc[] = '中文' . $message;
                        break;
                    case 'chinese_alpha':
                        $filters_desc[] = '中文或英文' . $message;
                        break;
                    case 'chinese_alpha_num':
                        $filters_desc[] = '中文、英文、数字' . $message;
                        break;
                    case 'chinese_alpha_num_dash':
                        $filters_desc[] = '中文、英文、数字、-、_' . $message;
                        break;
                    case 'alpha':
                        $filters_desc[] = '英文' . $message;
                        break;
                    case 'alpha_num':
                        $filters_desc[] = '英文或数字' . $message;
                        break;
                    case 'alpha_num_dash':
                        $filters_desc[] = '英文、数字、-、_格式' . $message;
                        break;
                    case 'url':
                        $filters_desc[] = 'url' . $message;
                        break;
                    case 'number':
                        $filters_desc[] = '数字' . $message;
                        break;
                    case 'tel':
                        $filters_desc[] = '固话' . $message;
                        break;
                    case 'array':
                        $filters_desc[] = '数组' . $message;
                        break;
                    case 'unique':
                        $filters_desc[] = '唯一值' . $message;
                        break;
                    case 'is_date':
                        $filters_desc[] = '时间格式' . $message;
                        break;
                    case 'is_domain':
                        $filters_desc[] = '域名' . $message;
                        break;
                    case 'is_json':
                        $filters_desc[] = 'json' . $message;
                        break;
                }
            }
        }
        return empty($filters_desc) ? '无' : implode('; ', $filters_desc);
    }

    /**
     * 获取校验
     * @return mixed
     */
    public function fetchVerifies() {
        $verifies = [];
        if (array_key_exists('verifies', $this->field_config)) {
            $verifies = $this->field_config['verifies'];
        }
        $this->field_config = [];
        return $verifies;
    }

    /**
     * 校验字段值
     * @param $fields
     * @param array $fields_verifies
     * @param string $type
     * @param null $instance
     * @return \support\Response|null
     * @author SongKeJing qq:597481334 mobile:159-5107-8050
     * @date 2021/6/11 17:59
     */
    public function verifyFields($fields, $fields_verifies = [], $type = 'insert', $instance = null) {
        //去除无需校验的字段
        foreach ($fields as $k => $each_field) {
            if (is_object($each_field)) {
                //可能是表达式
                unset($fields[$k]);
                continue;
            }
            if (is_array($each_field) && array_key_exists(0, $each_field)) {
                if (in_array($each_field[0], ['exp', 'inc', 'dec'])) {
                    unset($fields[$k]);
                    continue;
                }
            }
        }
        $error_msg = '';
        foreach ($fields_verifies as $k_field => $each_verify) {
            foreach ($each_verify as $v_verify) {
                if (is_array($v_verify)) {
                    if (strpos($v_verify[0], ':') !== false) {
                        list($v_verify[0], self::$msg) = explode(':', $v_verify[0]);
                    } else {
                        self::$msg = '';
                    }
                    switch ($v_verify[0]) {
                        case 'password':
                            if ($this->fieldNeedCheck($fields, $k_field)) {
                                if (is_array($fields[$k_field])) {
                                    foreach ($fields[$k_field] as $each_value) {
                                        if (!ClVerify::isPassword($each_value, $v_verify[1], $v_verify[2])) {
                                            $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                            break;
                                        }
                                    }
                                } else {
                                    if (!ClVerify::isPassword($fields[$k_field], $v_verify[1], $v_verify[2])) {
                                        $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                    }
                                }
                            }
                            break;
                        case 'in_array':
                            if ($this->fieldNeedCheck($fields, $k_field)) {
                                if (is_array($fields[$k_field])) {
                                    foreach ($fields[$k_field] as $each_value) {
                                        if (!in_array($each_value, $v_verify[1])) {
                                            $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                            break;
                                        }
                                    }
                                } else {
                                    if (!in_array($fields[$k_field], $v_verify[1])) {
                                        $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                    }
                                }
                            }
                            break;
                        case 'in_scope':
                            if ($this->fieldNeedCheck($fields, $k_field)) {
                                if (is_array($fields[$k_field])) {
                                    foreach ($fields[$k_field] as $each_value) {
                                        if ($each_value < $v_verify[1] || $each_value > $v_verify[2]) {
                                            $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                            break;
                                        }
                                    }
                                } else {
                                    if ($fields[$k_field] < $v_verify[1] || $fields[$k_field] > $v_verify[2]) {
                                        $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                    }
                                }
                            }
                            break;
                        case 'max':
                            if ($this->fieldNeedCheck($fields, $k_field)) {
                                if (is_array($fields[$k_field])) {
                                    foreach ($fields[$k_field] as $each_value) {
                                        if ($each_value > $v_verify[1]) {
                                            $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                            break;
                                        }
                                    }
                                } else {
                                    if ($fields[$k_field] > $v_verify[1]) {
                                        $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                    }
                                }
                            }
                            break;
                        case 'min':
                            if ($this->fieldNeedCheck($fields, $k_field)) {
                                if (is_array($fields[$k_field])) {
                                    foreach ($fields[$k_field] as $each_value) {
                                        if ($each_value < $v_verify[1]) {
                                            $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                            break;
                                        }
                                    }
                                } else {
                                    if ($fields[$k_field] < $v_verify[1]) {
                                        $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                    }
                                }
                            }
                            break;
                        case 'length':
                            if ($this->fieldNeedCheck($fields, $k_field)) {
                                if (is_array($fields[$k_field])) {
                                    foreach ($fields[$k_field] as $each_value) {
                                        if (ClString::getLength($each_value) != $v_verify[1]) {
                                            $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                            break;
                                        }
                                    }
                                } else {
                                    if (ClString::getLength($fields[$k_field]) != $v_verify[1]) {
                                        $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                    }
                                }
                            }
                            break;
                        case 'length_max':
                            if ($this->fieldNeedCheck($fields, $k_field)) {
                                if (is_array($fields[$k_field])) {
                                    foreach ($fields[$k_field] as $each_value) {
                                        if (ClString::getLength($each_value) > $v_verify[1]) {
                                            $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                            break;
                                        }
                                    }
                                } else {
                                    if (ClString::getLength($fields[$k_field]) > $v_verify[1]) {
                                        $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                    }
                                }
                            }
                            break;
                        case 'length_min':
                            if ($this->fieldNeedCheck($fields, $k_field)) {
                                if (is_array($fields[$k_field])) {
                                    foreach ($fields[$k_field] as $each_value) {
                                        if (ClString::getLength($each_value) < $v_verify[1]) {
                                            $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                            break;
                                        }
                                    }
                                } else {
                                    if (ClString::getLength($fields[$k_field]) < $v_verify[1]) {
                                        $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                    }
                                }
                            }
                            break;
                    }
                } else {
                    if (strpos($v_verify, ':') !== false) {
                        list($v_verify, self::$msg) = explode(':', $v_verify);
                    } else {
                        self::$msg = '';
                    }
                    switch ($v_verify) {
                        case 'is_required':
                            //更新不必判断是否必须，必须字段是在新增的时候判断
                            if ($type == 'update') {
                                if (array_key_exists($k_field, $fields) && !$this->fieldNeedCheck($fields, $k_field)) {
                                    $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                }
                            } else {
                                if (!array_key_exists($k_field, $fields) || !$this->fieldNeedCheck($fields, $k_field)) {
                                    $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                }
                            }
                            break;
                        case 'email':
                            if ($this->fieldNeedCheck($fields, $k_field)) {
                                if (is_array($fields[$k_field])) {
                                    foreach ($fields[$k_field] as $each_value) {
                                        if (!ClVerify::isEmail($each_value)) {
                                            $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                            break;
                                        }
                                    }
                                } else {
                                    if (!ClVerify::isEmail($fields[$k_field])) {
                                        $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                    }
                                }
                            }
                            break;
                        case 'mobile':
                            if ($this->fieldNeedCheck($fields, $k_field)) {
                                if (is_array($fields[$k_field])) {
                                    foreach ($fields[$k_field] as $each_value) {
                                        if (!ClVerify::isMobile($each_value)) {
                                            $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                            break;
                                        }
                                    }
                                } else {
                                    if (!ClVerify::isMobile($fields[$k_field])) {
                                        $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                    }
                                }
                            }
                            break;
                        case 'ip':
                            if ($this->fieldNeedCheck($fields, $k_field)) {
                                if (is_array($fields[$k_field])) {
                                    foreach ($fields[$k_field] as $each_value) {
                                        if (!ClVerify::isIp($each_value)) {
                                            $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                            break;
                                        }
                                    }
                                } else {
                                    if (!ClVerify::isIp($fields[$k_field])) {
                                        $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                    }
                                }
                            }
                            break;
                        case 'postcode':
                            if ($this->fieldNeedCheck($fields, $k_field)) {
                                if (is_array($fields[$k_field])) {
                                    foreach ($fields[$k_field] as $each_value) {
                                        if (!ClVerify::isPostcode($each_value)) {
                                            $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                            break;
                                        }
                                    }
                                } else {
                                    if (!ClVerify::isPostcode($fields[$k_field])) {
                                        $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                    }
                                }
                            }
                            break;
                        case 'id_card':
                            if ($this->fieldNeedCheck($fields, $k_field)) {
                                if (is_array($fields[$k_field])) {
                                    foreach ($fields[$k_field] as $each_value) {
                                        if (!ClVerify::isIdCard($each_value)) {
                                            $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                            break;
                                        }
                                    }
                                } else {
                                    if (!ClVerify::isIdCard($fields[$k_field])) {
                                        $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                    }
                                }
                            }
                            break;
                        case 'chinese':
                            if ($this->fieldNeedCheck($fields, $k_field)) {
                                if (is_array($fields[$k_field])) {
                                    foreach ($fields[$k_field] as $each_value) {
                                        if (!ClVerify::isChinese($each_value)) {
                                            $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                            break;
                                        }
                                    }
                                } else {
                                    if (!ClVerify::isChinese($fields[$k_field])) {
                                        $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                    }
                                }
                            }
                            break;
                        case 'chinese_alpha':
                            if ($this->fieldNeedCheck($fields, $k_field)) {
                                if (is_array($fields[$k_field])) {
                                    foreach ($fields[$k_field] as $each_value) {
                                        if (!ClVerify::isChineseAlpha($each_value)) {
                                            $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                            break;
                                        }
                                    }
                                } else {
                                    if (!ClVerify::isChineseAlpha($fields[$k_field])) {
                                        $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                    }
                                }
                            }
                            break;
                        case 'chinese_alpha_num':
                            if ($this->fieldNeedCheck($fields, $k_field)) {
                                if (is_array($fields[$k_field])) {
                                    foreach ($fields[$k_field] as $each_value) {
                                        if (!ClVerify::isChineseAlphaNum($each_value)) {
                                            $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                            break;
                                        }
                                    }
                                } else {
                                    if (!ClVerify::isChineseAlphaNum($fields[$k_field])) {
                                        $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                    }
                                }
                            }
                            break;
                        case 'chinese_alpha_num_dash':
                            if ($this->fieldNeedCheck($fields, $k_field)) {
                                if (is_array($fields[$k_field])) {
                                    foreach ($fields[$k_field] as $each_value) {
                                        if (!ClVerify::isChineseAlphaNumDash($each_value)) {
                                            $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                            break;
                                        }
                                    }
                                } else {
                                    if (!ClVerify::isChineseAlphaNumDash($fields[$k_field])) {
                                        $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                    }
                                }
                            }
                            break;
                        case 'alpha':
                            if ($this->fieldNeedCheck($fields, $k_field)) {
                                if (is_array($fields[$k_field])) {
                                    foreach ($fields[$k_field] as $each_value) {
                                        if (!ClVerify::isAlpha($each_value)) {
                                            $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                            break;
                                        }
                                    }
                                } else {
                                    if (!ClVerify::isAlpha($fields[$k_field])) {
                                        $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                    }
                                }
                            }
                            break;
                        case 'alpha_num':
                            if ($this->fieldNeedCheck($fields, $k_field)) {
                                if (is_array($fields[$k_field])) {
                                    foreach ($fields[$k_field] as $each_value) {
                                        if (!ClVerify::isAlphaNum($each_value)) {
                                            $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                            break;
                                        }
                                    }
                                } else {
                                    if (!ClVerify::isAlphaNum($fields[$k_field])) {
                                        $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                    }
                                }
                            }
                            break;
                        case 'alpha_num_dash':
                            if ($this->fieldNeedCheck($fields, $k_field)) {
                                if (is_array($fields[$k_field])) {
                                    foreach ($fields[$k_field] as $each_value) {
                                        if (!ClVerify::isAlphaNumDash($each_value)) {
                                            $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                            break;
                                        }
                                    }
                                } else {
                                    if (!ClVerify::isAlphaNumDash($fields[$k_field])) {
                                        $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                    }
                                }
                            }
                            break;
                        case 'url':
                            if ($this->fieldNeedCheck($fields, $k_field)) {
                                if (is_array($fields[$k_field])) {
                                    foreach ($fields[$k_field] as $each_value) {
                                        if (!ClVerify::isUrl($each_value)) {
                                            $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                            break;
                                        }
                                    }
                                } else {
                                    if (!ClVerify::isUrl($fields[$k_field])) {
                                        $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                    }
                                }
                            }
                            break;
                        case 'number':
                            if ($this->fieldNeedCheck($fields, $k_field)) {
                                if (is_array($fields[$k_field])) {
                                    foreach ($fields[$k_field] as $each_value) {
                                        if (!is_numeric($each_value)) {
                                            $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                            break;
                                        }
                                    }
                                } else {
                                    if (!is_numeric($fields[$k_field])) {
                                        $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                    }
                                }
                            }
                            break;
                        case 'tel':
                            if ($this->fieldNeedCheck($fields, $k_field)) {
                                if (is_array($fields[$k_field])) {
                                    foreach ($fields[$k_field] as $each_value) {
                                        if (!ClVerify::isTel($each_value)) {
                                            $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                            break;
                                        }
                                    }
                                } else {
                                    if (!ClVerify::isTel($fields[$k_field])) {
                                        $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                    }
                                }
                            }
                            break;
                        case 'array':
                            if ($this->fieldNeedCheck($fields, $k_field)) {
                                if (!is_array($fields[$k_field])) {
                                    $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                }
                            }
                            break;
                        case 'unique':
                            if ($this->fieldNeedCheck($fields, $k_field) && !is_null($instance)) {
                                $new_instance = $instance::instance(999999);
                                if (!$new_instance->is_divide_table) {
                                    if ($type == 'insert') {
                                        //插入，则只需要判断是否存在
                                        $count = $new_instance->where([
                                            $k_field => $fields[$k_field]
                                        ])->count();
                                        if ($count > 0) {
                                            $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                        }
                                    } else {
                                        //更新，则要判断where条件
                                        $field_id = $new_instance->where([$k_field => $fields[$k_field]])->value($new_instance->getPk());
                                        if (!empty($field_id)) {
                                            //存在值的情况
                                            $where    = $instance->getOptions('where');
                                            $where_id = $new_instance->where($where['AND'])->value($new_instance->getPk());
                                            if ($field_id != $where_id) {
                                                //两个结果记录不同，则不可更新
                                                $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                            }
                                        }
                                    }
                                }
                            }
                            break;
                        case 'is_date':
                            if ($this->fieldNeedCheck($fields, $k_field)) {
                                if (is_array($fields[$k_field])) {
                                    foreach ($fields[$k_field] as $each_value) {
                                        if (!ClVerify::isDate($each_value)) {
                                            $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                            break;
                                        }
                                    }
                                } else {
                                    if (!ClVerify::isDate($fields[$k_field])) {
                                        $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                    }
                                }
                            }
                            break;
                        case 'is_domain':
                            if ($this->fieldNeedCheck($fields, $k_field)) {
                                if (is_array($fields[$k_field])) {
                                    foreach ($fields[$k_field] as $each_value) {
                                        if (!ClVerify::isDomain($each_value)) {
                                            $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                            break;
                                        }
                                    }
                                } else {
                                    if (!ClVerify::isDomain($fields[$k_field])) {
                                        $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                    }
                                }
                            }
                            break;
                        case 'is_json':
                            if ($this->fieldNeedCheck($fields, $k_field)) {
                                if (is_array($fields[$k_field])) {
                                    foreach ($fields[$k_field] as $each_value) {
                                        if (!ClVerify::isJson($each_value)) {
                                            $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                            break;
                                        }
                                    }
                                } else {
                                    if (!ClVerify::isJson($fields[$k_field])) {
                                        $error_msg = $this->getErrorMsg($v_verify, $fields, $k_field, $instance);
                                    }
                                }
                            }
                            break;
                    }
                }
            }
            if (!empty($error_msg)) {
                break;
            }
        }
        if (!empty($error_msg)) {
            $data = [
                'status'  => -1,
                'message' => $error_msg
            ];
            if (is_array($fields) && !empty($fields)) {
                $data['data'] = $fields;
            }
            //返回
            return $data;
        }
        return null;
    }

    /**
     * 获取字段描述
     * @param $key_field
     * @param BaseModel|null $instance
     * @return string
     */
    private function getFieldDesc($key_field, BaseModel $instance = null) {
        if (is_null($instance)) {
            return $key_field;
        }
        if (array_key_exists($key_field, $instance::instance()->fields_names) && !empty($instance::instance()->fields_names[$key_field])) {
            return sprintf('%s.%s(%s)', $instance->getTable(), $key_field, $instance::instance()->fields_names[$key_field]);
        } else {
            return sprintf('%s.%s', $instance->getTable(), $key_field);
        }
    }

    /**
     * 字段是否校验
     * @param $fields
     * @param $k_field
     * @return bool
     */
    private function fieldNeedCheck($fields, $k_field) {
        //不存在，不进行校验
        if (!array_key_exists($k_field, $fields)) {
            return false;
        }
        //是数字，则进行校验
        if (is_numeric($fields[$k_field])) {
            return true;
        }
        //为空，不进行校验
        if (empty($fields[$k_field]) && !is_bool($fields[$k_field])) {
            return false;
        }
        //其余情况，进行校验
        return true;
    }

    /**
     * 获取错误信息
     * @param $verify
     * @param $fields
     * @param $k_field
     * @param null $instance
     * @return string
     */
    private function getErrorMsg($verify, $fields, $k_field, $instance = null) {
        if (!empty(self::$msg)) {
            return self::$msg;
        }
        if (array_key_exists($k_field, $fields)) {
            $fields[$k_field] = is_string($fields[$k_field]) ? $fields[$k_field] : json_encode($fields[$k_field], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
        } else {
            $fields[$k_field] = '';
        }
        switch ((is_array($verify) ? $verify[0] : $verify)) {
            case 'password':
                $error_msg = sprintf('%s:“%s” 密码长度%s~%s，且只能包含字符、数字和下划线', $this->getFieldDesc($k_field, $instance), $fields[$k_field], $verify[1], $verify[2]);
                break;
            case 'in_array':
                $error_msg = sprintf('%s:“%s” 不在%s数组内', $this->getFieldDesc($k_field, $instance), $fields[$k_field], json_encode($verify[1], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
                break;
            case 'in_scope':
                $error_msg = sprintf('%s:“%s” 不在[%s, %s]区间内', $this->getFieldDesc($k_field, $instance), $fields[$k_field], $verify[1], $verify[2]);
                break;
            case 'max':
                $error_msg = sprintf('%s:“%s” 最大值%s', $this->getFieldDesc($k_field, $instance), $fields[$k_field], $verify[1]);
                break;
            case 'min':
                $error_msg = sprintf('%s:“%s” 最小值%s', $this->getFieldDesc($k_field, $instance), $fields[$k_field], $verify[1]);
                break;
            case 'length':
                $error_msg = sprintf('%s:“%s” 长度为%s', $this->getFieldDesc($k_field, $instance), $fields[$k_field], $verify[1]);
                break;
            case 'length_max':
                $error_msg = sprintf('%s:“%s” 最大长度%s', $this->getFieldDesc($k_field, $instance), $fields[$k_field], $verify[1]);
                break;
            case 'length_min':
                $error_msg = sprintf('%s:“%s” 最小长度%s', $this->getFieldDesc($k_field, $instance), $fields[$k_field], $verify[1]);
                break;
            case 'is_required':
                $error_msg = sprintf('%s 为必填项', $this->getFieldDesc($k_field, $instance));
                break;
            case 'email':
                $error_msg = sprintf('%s:“%s” 邮箱格式错误', $this->getFieldDesc($k_field, $instance), $fields[$k_field]);
                break;
            case 'mobile':
                $error_msg = sprintf('%s:“%s” 手机号码格式错误', $this->getFieldDesc($k_field, $instance), $fields[$k_field]);
                break;
            case 'ip':
                $error_msg = sprintf('%s:“%s” ip格式错误', $this->getFieldDesc($k_field, $instance), $fields[$k_field]);
                break;
            case 'postcode':
                $error_msg = sprintf('%s:“%s” 邮编格式错误', $this->getFieldDesc($k_field, $instance), $fields[$k_field]);
                break;
            case 'id_card':
                $error_msg = sprintf('%s:“%s” 身份证格式错误', $this->getFieldDesc($k_field, $instance), $fields[$k_field]);
                break;
            case 'chinese':
                $error_msg = sprintf('%s:“%s” 中文格式错误', $this->getFieldDesc($k_field, $instance), $fields[$k_field]);
                break;
            case 'chinese_alpha':
                $error_msg = sprintf('%s:“%s” 中文、英文格式错误', $this->getFieldDesc($k_field, $instance), $fields[$k_field]);
                break;
            case 'chinese_alpha_num':
                $error_msg = sprintf('%s:“%s” 中文、英文、数字格式错误', $this->getFieldDesc($k_field, $instance), $fields[$k_field]);
                break;
            case 'chinese_alpha_num_dash':
                $error_msg = sprintf('%s:“%s” 中文、英文、数字、-、_格式错误', $this->getFieldDesc($k_field, $instance), $fields[$k_field]);
                break;
            case 'alpha':
                $error_msg = sprintf('%s:“%s” 英文格式错误', $this->getFieldDesc($k_field, $instance), $fields[$k_field]);
                break;
            case 'alpha_num':
                $error_msg = sprintf('%s:“%s” 英文、数字格式错误', $this->getFieldDesc($k_field, $instance), $fields[$k_field]);
                break;
            case 'alpha_num_dash':
                $error_msg = sprintf('%s:“%s” 英文、数字、-、_格式错误', $this->getFieldDesc($k_field, $instance), $fields[$k_field]);
                break;
            case 'url':
                $error_msg = sprintf('%s:“%s” url格式错误', $this->getFieldDesc($k_field, $instance), $fields[$k_field]);
                break;
            case 'number':
                $error_msg = sprintf('%s:“%s” 数字格式错误', $this->getFieldDesc($k_field, $instance), $fields[$k_field]);
                break;
            case 'tel':
                $error_msg = sprintf('%s:“%s” 固话格式错误', $this->getFieldDesc($k_field, $instance), $fields[$k_field]);
                break;
            case 'array':
                $error_msg = sprintf('%s:“%s” 数组格式错误', $this->getFieldDesc($k_field, $instance), $fields[$k_field]);
                break;
            case 'unique':
                $error_msg = sprintf('%s:“%s” 值已存在，不可重复', $this->getFieldDesc($k_field, $instance), $fields[$k_field]);
                break;
            case 'is_date':
                $error_msg = sprintf('%s:“%s” 时间格式错误', $this->getFieldDesc($k_field, $instance), $fields[$k_field]);
                break;
            case 'is_domain':
                $error_msg = sprintf('%s:“%s” 域名格式错误', $this->getFieldDesc($k_field, $instance), $fields[$k_field]);
                break;
            case 'is_json':
                $error_msg = sprintf('%s:“%s” json格式错误', $this->getFieldDesc($k_field, $instance), $fields[$k_field]);
                break;
        }
        //日志记录
        log_info('error:', $error_msg, ClCache::getFunctionHistory(-1));
        if (strpos($error_msg, ':') !== false) {
            //返回第二个段
            $error_msg = explode(':', $error_msg);
            $error_msg = $error_msg[1];
        }
        return $error_msg;
    }

}